package xx.iverson.file_manager.util;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import xx.iverson.file_manager.entity.FileInfo;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.UUID;

/**
 * xx.iverson.file_manager.util.FileUploadUtil
 * 描述：
 * on 2025/9/22-上午11:14
 *
 * @author weijx
 */


@Component
public class FileUploadUtil {

    @Value("${file.upload-dir}")
    private String uploadPath;

    @Value("${file.chunk-dir}")
    private String tempDir;

    @Value("${file.upload.chunk-size}")
    private long chunkSize;

    /**
     * 生成存储文件名
     */
    public String generateStorageName(String originalFileName) {
        String extension = "";
        if (originalFileName.contains(".")) {
            extension = originalFileName.substring(originalFileName.lastIndexOf("."));
        }
        return UUID.randomUUID().toString() + extension;
    }

    /**
     * 处理分片上传
     */
    public boolean processChunk(MultipartFile chunk, String fileMd5, Integer chunkIndex, Integer totalChunks) throws IOException {
        // 创建临时目录
        File tempDirFile = new File(tempDir + File.separator + fileMd5);
        if (!tempDirFile.exists()) {
            tempDirFile.mkdirs();
        }

        // 保存分片
        File chunkFile = new File(tempDirFile, chunkIndex.toString());
        chunk.transferTo(chunkFile);

        return true;
    }

    /**
     * 合并分片
     */
    public FileInfo mergeChunks(String fileMd5, String originalFileName, String fileDescription,String fileType, Long fileSize, Integer categoryId) throws IOException {
        // 临时目录
        File tempDirFile = new File(tempDir + File.separator + fileMd5);
        File[] chunks = tempDirFile.listFiles();

        if (chunks == null || chunks.length == 0) {
            throw new IOException("没有找到分片文件");
        }

        // 生成存储文件名和路径
        String storageName = generateStorageName(originalFileName);
        String filePath = getString(storageName, chunks, tempDirFile);

        // 删除临时目录
        tempDirFile.delete();

        // 创建文件信息对象
        FileInfo fileInfo = new FileInfo();
        fileInfo.setOriginalName(originalFileName);
        fileInfo.setStorageName(storageName);
        fileInfo.setFileDescription(fileDescription);
        fileInfo.setFilePath(filePath);
        fileInfo.setFileSize(fileSize);
        fileInfo.setFileType(fileType);
        fileInfo.setCategoryId(categoryId);
        fileInfo.setDownloadCount(0);
        fileInfo.setUploadTime(LocalDateTime.now());
        fileInfo.setUpdateTime(LocalDateTime.now());

        return fileInfo;
    }

    private String getString(String storageName, File[] chunks, File tempDirFile) throws IOException {
        String filePath = uploadPath + File.separator + storageName;

        // 确保上传目录存在
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }

        // 合并文件
        try (RandomAccessFile mergedFile = new RandomAccessFile(filePath, "rw")) {
            byte[] buffer = new byte[1024 * 1024]; // 1MB缓冲区
            for (int i = 0; i < chunks.length; i++) {
                File chunkFile = new File(tempDirFile, String.valueOf(i));
                try (RandomAccessFile chunk = new RandomAccessFile(chunkFile, "r")) {
                    long chunkLength = chunk.length();
                    long bytesRead = 0;
                    while (bytesRead < chunkLength) {
                        int read = chunk.read(buffer);
                        if (read == -1) {
                            break;
                        }
                        mergedFile.write(buffer, 0, read);
                        bytesRead += read;
                    }
                }
                // 删除分片
                chunkFile.delete();
            }
        }
        return filePath;
    }

    /**
     * 检查分片是否存在
     */
    public boolean checkChunk(String fileMd5, Integer chunkIndex) {
        File chunkFile = new File(tempDir + File.separator + fileMd5 + File.separator + chunkIndex.toString());
        return chunkFile.exists();
    }

    /**
     * 获取已上传的分片列表
     */
    public Integer[] getUploadedChunks(String fileMd5) {
        File tempDirFile = new File(tempDir + File.separator + fileMd5);
        if (!tempDirFile.exists() || !tempDirFile.isDirectory()) {
            return new Integer[0];
        }

        File[] files = tempDirFile.listFiles((dir, name) -> name.matches("\\d+"));
        if (files == null) {
            return new Integer[0];
        }

        return Arrays.stream(files)
                .map(file -> Integer.parseInt(file.getName()))
                .toArray(Integer[]::new);
    }

}